
#include "obj_string.h"
#include "common.h"
#include "utils.h"
#include "vm.h"

/**
 * @brief fnv-la算法
*/
uint32_t hash_string(char *str, uint32_t length)
{
    uint32_t hash_code = 2166136261, idx = 0;
    while (idx < length)
    {
        hash_code ^= str[idx];
        hash_code *= 16777619;
        idx ++;
    }
    return hash_code;
}

/**
 * @brief 为string计算哈希码并将值存储到string->hash
*/
void hash_objString(ObjString *obj_string)
{
    obj_string->hash_code = hash_string(obj_string->value.start, obj_string->value.length);
}

/**
 * @brief 以str字符串创建Objstring对象，允许空串""
*/
ObjString* new_objString(VM *vm, const char *str, uint32_t length)
{
    ASSERT(length == 0 || str != NULL, "str length don't match str!");

    ObjString *obj_strng = ALLOCATE_EXTRA(vm, ObjString, length + 1);

    if (obj_strng != NULL)
    {
        init_objheader(vm, &obj_strng->obj_header, OT_STRING, vm->string_class);
        obj_strng->value.length = length;

        // 支持空字符串:str为null，length为0
        if (length > 0)
        {
            memcpy(obj_strng->value.start, str, length);
        }
        obj_strng->value.start[length] = '\0';
        hash_objString(obj_strng);
    }
    else
    {
        MEM_ERROR("Allocating ObjString failed!");
    }
    return obj_strng;
}